package top.jacktgq.lock.reentrantLock;

import java.util.concurrent.locks.ReentrantLock;

import top.jacktgq.utils.LogUtils;
import top.jacktgq.utils.Sleeper;
/**
 * 
 * @Title: TestReentrantLock.java 
 * @Package top.jacktgq.lock 
 * @Description: 测试ReentrantLock：可打断
 * @author CandyWall   
 * @date 2020年11月1日 下午5:49:07 
 * @version V1.0
 */
public class Demo2 {
	private static ReentrantLock lock = new ReentrantLock();
	public static void main(String[] args) {
		Thread t1 = new Thread(() -> {
			try {
				//如果没有竞争，此方法就会获取lock对象锁
				//如果有竞争，就会进入阻塞队列，可以被其他线程用interrupt方法打断
				LogUtils.log("Demo2", "尝试获得锁");
				//由于主线程获得了锁也没有释放， 会使得t1线程会阻塞在这里，程序一直不会退出
				lock.lockInterruptibly();
				//lock.lock();		//不会被打断
			} catch (InterruptedException e) {
				e.printStackTrace();
				LogUtils.log("Demo2", "没有获得锁，返回");
				return;
			}
			try {
				//同步代码块部分
				LogUtils.log("Demo2", "获取到锁");
			} finally {
				lock.unlock();
			}
			// 为啥必须用两个try catch
			// 如果合并了，获取锁的时候或者锁被打断了，会抛异常，
			// 然后会走finally块，但是因为没有获取到锁，所以解锁会出问题
		}, "t1");
		
		//主线程在t1线程启动前先获得了锁
		lock.lock();
		
		t1.start();
		Sleeper.sleep(1);
		LogUtils.log("Demo2", "打断t1");
		t1.interrupt();
	}
	
}
